package org.engine.core;

import com.alibaba.fastjson.JSONObject;
import org.engine.service.ILogWriter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;

/**
 * 抽象规则
 */
public abstract class AbstractRule {


    private static final Logger logger = LoggerFactory.getLogger(AbstractRule.class);

    protected String id;

    protected String name;
    /**
     * 规则执行时的配置信息，用于execute方法实现时与参数进行比较
     */
    protected JSONObject ruleConfig;
    /**
     * 子规则
     */
    protected List<AbstractRule> childrenRule;
    /**
     * 是否忽略规则的执行结果
     */
    protected boolean ignoreResult = false;
    /**
     * 是否执行所有的子规则策略 （忽略规则的逻辑判断 & ||）
     */
    protected boolean executeAllChildren = false;

    /**
     * 是否输出日志
     */
    protected boolean writeLog = false;

    /**
     * 日志服务
     */
    @Autowired
    protected ILogWriter logWriter;

    /**
     * 日志服务
     */
    public ExecuteResult execute(RuleEngineContext ruleEngineContext) {
        long startTime = System.currentTimeMillis();
        ExecuteResult executeResult = null;
        try {
            executeResult = executeBody(ruleEngineContext);
        } catch (Exception e) {
            logger.error("规则执行异常", e);
            executeResult = ExecuteResult.failResult("规则执行异常");
        }
        executeResult.setAbstractRule(this);
        executeResult.setConsumingTime(System.currentTimeMillis() - startTime);
        if (writeLog) {
            logWriter.addLog(executeResult, ruleEngineContext.getParams());
        }
        return executeResult;
    }

    /**
     * 具体执行
     */
    protected abstract ExecuteResult executeBody(RuleEngineContext ruleEngineContext);

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public List<AbstractRule> getChildrenRule() {
        return childrenRule;
    }

    public void setChildrenRule(List<AbstractRule> childrenRule) {
        this.childrenRule = childrenRule;
    }

    public boolean isIgnoreResult() {
        return ignoreResult;
    }

    public void setIgnoreResult(boolean ignoreResult) {
        this.ignoreResult = ignoreResult;
    }

    public boolean isExecuteAllChildren() {
        return executeAllChildren;
    }

    public void setExecuteAllChildren(boolean executeAllChildren) {
        this.executeAllChildren = executeAllChildren;
    }

    public boolean isWriteLog() {
        return writeLog;
    }

    public void setWriteLog(boolean writeLog) {
        this.writeLog = writeLog;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public JSONObject getRuleConfig() {
        return ruleConfig;
    }

    public void setRuleConfig(JSONObject ruleConfig) {
        this.ruleConfig = ruleConfig;
    }
}
